home *** CD-ROM | disk | FTP | other *** search
- %
- % "mat_util.t" contains matrix utility functions for use
- % in other programs.
- %
- % To use, add file to list in "*.prt" file
- %
- % Dimension 'DIM' should be declared as a global constant
- % in the main program file.
- %
- % Sample program for the T Interpreter by:
- %
- % Stephen R. Schmitt
- % 962 Depot Road
- % Boxborough, MA 01719
- %
-
- type rmatrix : array[DIM,DIM] of real
- type rvector : array[DIM] of real
- type ivector : array[DIM] of int
-
- %
- % print a matrix
- %
- procedure print_mat( var m : rmatrix )
-
- var i, j : int
-
- for i := 0...DIM-1 do
-
- for j := 0...DIM-1 do
-
- put m[i,j]:15:6...
-
- end for
-
- put ""
-
- end for
-
- end procedure
-
- %
- % return the absolute value of a real number
- %
- function rabs( x : real ) : real
-
- if x < 0.0 then
-
- x := -x
-
- end if
-
- return x
-
- end function
-
- %
- % invert a square matrix using Gauss-Jordan method
- %
- % note: pivoting will sometimes fail; set pivot to false to disable
- %
- function invert( var a, b : rmatrix, pivot : boolean ) : real
-
- var w : array[DIM,2*DIM] of real
- var p : array[DIM] of int
- var s, t, det : real
- var i, j, k : int
- label invert_exit :
-
- % setup workspace : [A|I]
-
- for i := 0...DIM-1 do
-
- for j := 0...DIM-1 do
-
- w[i,j] := a[i,j]
- w[i,j+DIM] := 0.0
-
- end for
-
- w[i,i+DIM] := 1.0
-
- end for
-
- det := 0.0
-
- % convert to upper triangular form
-
- for k := 0...DIM-2 do
-
- j := k
- t := 0.0
-
- if pivot then % find pivot row for column k
-
- for i := k...DIM-1 do
-
- s := rabs( w[i,k] )
-
- if s > t then
-
- t := s
- j := i
-
- end if
-
- end for
-
- end if
-
- p[k] := j % save pivot row number
-
- if j ~= k then % swap rows
-
- for i := k...2*DIM-1 do
-
- t := w[j,i]
- w[j,i] := w[k,i]
- w[k,i] := t
-
- end for
-
- end if
-
- end for
-
- p[DIM-1] := DIM - 1
-
- % zeroize elements below each diagonal element
-
- for k := 0...DIM-2 do
-
- if w[k,k] = 0.0 then
-
- goto invert_exit
-
- end if
-
- for i := k+1...DIM-1 do
-
- t := w[i,k] / w[k,k]
-
- for j := k...2*DIM-1 do
-
- w[i,j] := w[i,j] - t * w[k,j]
-
- end for
-
- end for
-
- end for
-
- % compute determinant
-
- det := 1.0
- i := 1
-
- for k := 0...DIM-1 do
-
- if p[k] ~= k then
-
- i := -i
-
- end if
-
- det := det * w[k,k]
-
- end for
-
- det := i * det
-
- % make diagonal elements = 1
-
- for k := 0...DIM-1 do
-
- t := w[k,k]
-
- for j := k...2*DIM-1 do
-
- w[k,j] := w[k,j] / t
-
- end for
-
- end for
-
- % zeroize elements above each diagonal element
-
- for decreasing k := DIM-1...1 do
-
- for decreasing i := k-1...0 do
-
- t := w[i,k]
-
- for j := k...2*DIM-1 do
-
- w[i,j] := w[i,j] - t * w[k,j]
-
- end for
-
- end for
-
- end for
-
- % output results
-
- for i := 0...DIM-1 do
-
- for j := 0...DIM-1 do
-
- b[i,j] := w[i,j+DIM]
-
- end for
-
- end for
-
-
- invert_exit :
-
- return det
-
- end function
-
- %
- % multiply two square matrices
- %
- procedure mul_mat_mat( var a, b, c : rmatrix )
-
- var i, j, k : int
- var s : real
-
- for i := 0...DIM-1 do
-
- for j := 0...DIM-1 do
-
- s := 0.0
-
- for k := 0...DIM-1 do
-
- s := s + a[i,k] * b[k,j]
-
- end for
-
- c[i,j] := s
-
- end for
-
- end for
-
- end procedure
-
- %
- % multiply a square matrix by a vector
- %
- procedure mul_mat_vec( var a : rmatrix, var x, y : rvector )
-
- var i, j : int
- var s : real
-
- for i := 0...DIM-1 do
-
- s := 0.0
-
- for j := 0...DIM-1 do
-
- s := s + a[i,j] * x[j]
-
- end for
-
- y[i] := s
-
- end for
-
- end procedure
-
- %
- % decompose a square matrix into symmetric and skew-symmetric parts
- %
- procedure sym_mat( var a, m, s : rmatrix )
-
- var i, j : int
-
- for i := 0...DIM-1 do
-
- for j := 0...DIM-1 do
-
- m[i,j] := ( a[i,j] + a[j,i] ) / 2
-
- end for
-
- end for
-
- for i := 0...DIM-1 do
-
- for j := 0...DIM-1 do
-
- s[i,j] := ( a[i,j] - a[j,i] ) / 2
-
- end for
-
- end for
-
- end procedure